import { create } from 'zustand'
import { immer } from 'zustand/middleware/immer'
import { FileBaseState, FileStateType, FolderType } from '@/types'

const backupStores: Record<Extract<FolderType, 'Note' | 'Mind'>, FileBaseState> = {
  Note: {
    folderPath: '',
    files: [],
    currentFile: null,
    expanded: 'expanded'
  },
  Mind: {
    folderPath: '',
    files: [],
    currentFile: null,
    expanded: 'expanded'
  }
}

export const useFilesStore = create<FileStateType>()(
  immer((set, get) => ({
    curType: 'Note', // 当前类型，默认为 Note
    curState: {
      folderPath: '',
      files: [],
      currentFile: null,
      expanded: 'none'
    },
    noteContent: '',
    mindContent: '',
    renamef: {
      renamingPath: '',
      renameValue: '',
      newFileName: ''
    },
    isCreatingFile: false,

    /** 设置当前类型的 store (Note/Mind) */
    setCurStore: async (v) => {
      const { type, ...otherState } = v
      // 如果传入了 type，则设置当前类型，使用 Note 或 Mind 的状态
      if (type && backupStores?.[type]) {
        backupStores[type] = {
          ...backupStores[type],
          ...otherState
        }
        set({
          curType: type,
          curState: backupStores[type]
        })
      } else if (type) {
        // 如果是待办事项
        set({
          curType: type
        })
      }
      // 没传 覆盖 当前类型的状态 以及原始状态
      else {
        const { curType } = get()

        set((s) => {
          const keys = Object.keys(otherState) as (keyof FileBaseState)[]

          keys.forEach((key) => {
            if (key in s.curState) {
              s.curState[key] = otherState[key] as any
            }
          })

          backupStores[curType] = {
            ...backupStores[curType],
            ...otherState
          }
        })
      }
      console.log('执行完毕')
      return {
        curType: type,
        curState: backupStores?.[type ?? get().curType]
      }
    },

    /** 初始化：读取两类保存的文件夹路径并加载文件列表 */
    initFromSaved: async () => {
      const [noteSaved, mindSaved] = await Promise.all([
        window.fsApi?.getFolder('Note'),
        window.fsApi?.getFolder('Mind')
      ])

      const [noteList, mindList] = await Promise.all([
        noteSaved ? window.fsApi?.listMd(noteSaved) : Promise.resolve([]),
        mindSaved ? window.fsApi?.listMd(mindSaved) : Promise.resolve([])
      ])

      const noteFiles = (noteList || []).filter((f) => f.fileType === '.md')
      const mindFiles = (mindList || []).filter((f) => f.fileType === '.json')

      set((s) => {
        if (noteSaved) {
          backupStores.Note = {
            ...backupStores.Note,
            folderPath: noteSaved,
            files: noteFiles
          }
        }
        if (mindSaved) {
          backupStores.Mind = {
            ...backupStores.Mind,
            folderPath: mindSaved,
            files: mindFiles
          }
        }
        s.curState = { ...backupStores[s.curType] }
      })
    },

    /** 刷新当前文件列表 */
    refreshFiles: async ({ type, updateContent } = {}) => {
      const { curState, curType, setCurStore, setContent } = get()

      if (!curState.folderPath) return

      const finaltype = type || curType
      const curBackupState = backupStores[finaltype]

      const list = await window.fsApi?.listMd(curBackupState.folderPath)

      const ext = finaltype === 'Mind' ? '.json' : '.md'
      const filtered = (list || []).filter((f) => f.fileType === ext)

      setCurStore(type ? { type, files: filtered } : { files: filtered })

      // 如果存在当前打开的文件，重新读取内容
      if (curState.currentFile?.path && updateContent) {
        const content = await window.fsApi?.readFile(curBackupState.currentFile?.path)
        setContent(content || '')
      }
    },

    /** 选择文件夹并更新 store */
    chooseFolder: async () => {
      const res = await window.fsApi?.openFolder()
      if (!res?.folderPath) return
      const { curType } = get()

      get().setCurStore({
        folderPath: res.folderPath,
        files: (res.files || []).filter(
          (f) => f.fileType === (curType === 'Mind' ? '.json' : '.md')
        )
      })
      if (curType === 'Note' || curType === 'Mind') {
        window.fsApi?.setFolder(curType, res.folderPath)
      }
    },

    /** 打开文件并读取内容 */
    openFile: async (currentFile) => {
      console.log('打开文件', currentFile)

      const content = await window.fsApi?.readFile(currentFile.path)

      get().setCurStore({
        currentFile
      })
      get().setContent(content || '')
    },

    /** 创建新文件（使用 renamef.newFileName） */
    createFile: async () => {
      const { renamef } = get()
      const { curState } = get()

      const newName = renamef.newFileName
      if (!curState.folderPath || !newName) return

      const isMind = get().curType === 'Mind'
      const ext = isMind ? '.json' : '.md'
      const finalName = newName.endsWith(ext) ? newName : `${newName}${ext}`
      const filePath = `${curState.folderPath}/${finalName}`

      await window.fsApi?.writeFile(filePath, isMind ? '{}' : '# ' + newName)
      await get().refreshFiles()

      set((s) => {
        s.isCreatingFile = false
        s.renamef.newFileName = ''
      })
    },

    /** 设置文件内容 */
    setContent: (content) => {
      set((s) => {
        if (s.curType === 'Note') {
          s.noteContent = content || ''
        } else if (s.curType === 'Mind') {
          s.mindContent = content || ''
        }
        // 本地修改
        s.curState.currentFile?.path &&
          window.fsApi.writeFile(s.curState.currentFile.path, content || '')
      })
    },

    /** 删除文件，如果刚好删除当前文件则清空内容 */
    deleteFile: async (filePath) => {
      console.log('删除文件', filePath)

      const ok = await window.fsApi?.deleteFile(filePath)
      if (!ok) return

      const { curState, setCurStore, setContent } = get()

      if (curState.currentFile?.path === filePath) {
        setCurStore({ currentFile: null })
        setContent('')
      }

      await get().refreshFiles()
    },

    /** 开始重命名文件，记录旧名称 */
    startRename: (filePath) => {
      const { curState } = get()
      const file = curState.files.find((f) => f.path === filePath)
      if (!file) return

      set((s) => {
        s.renamef.renamingPath = filePath
        s.renamef.renameValue = file.fileName
        s.isCreatingFile = false
        s.renamef.newFileName = ''
      })
    },

    /** 确认重命名并更新文件信息 */
    confirmRename: async () => {
      console.log('确认重命名')

      const { renamef } = get()
      const { renamingPath, renameValue } = renamef
      if (!renamingPath || !renameValue) return

      const ext = get().curType === 'Mind' ? '.json' : '.md'
      const finalName = renameValue.endsWith(ext) ? renameValue : `${renameValue}${ext}`
      const newPath = await window.fsApi?.renameFile(renamingPath, finalName)

      // 清空重命名状态
      set((s) => {
        s.renamef.renamingPath = ''
        s.renamef.renameValue = ''
      })

      const { curState, setCurStore, setContent } = get()
      const cur = curState.currentFile

      // 如果正在重命名的是当前文件
      if (cur?.path === renamingPath) {
        if (newPath) {
          setCurStore({
            currentFile: {
              ...cur,
              path: newPath,
              fileName: renameValue,
              fileFullName: finalName
            }
          })
        } else {
          setCurStore({ currentFile: null })
          setContent('')
        }
      }

      if (newPath) await get().refreshFiles()
    },

    /** 取消重命名 */
    cancelRename: () => {
      set((s) => {
        s.renamef.renamingPath = ''
        s.renamef.renameValue = ''
      })
    },

    /** 设置 renameValue */
    setRenameValue: (v) =>
      set((s) => {
        s.renamef.renameValue = v
      }),

    /** 设置 newFileName */
    setNewFileName: (v) =>
      set((s) => {
        s.renamef.newFileName = v
      }),

    /** 设置是否正在创建文件 */
    setIsCreatingFile: (v) =>
      set((s) => {
        s.isCreatingFile = v
      }),

    /** 开始创建文件 */
    startCreateFile: () =>
      set((s) => {
        s.isCreatingFile = true
        s.renamef.renamingPath = ''
        s.renamef.renameValue = ''
      }),

    /** 取消创建文件 */
    cancelCreateFile: () =>
      set((s) => {
        s.isCreatingFile = false
        s.renamef.newFileName = ''
      }),

    /** 设置树的展开状态 */
    setExpanded: (v) => {
      console.log('设置展开状态', v)

      get().setCurStore({ expanded: v })
    }
  }))
)
